package com.ricchieri.manage.bean;

import java.util.Date;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;

import org.primefaces.context.RequestContext;
import org.primefaces.event.FlowEvent;
import org.primefaces.event.SelectEvent;

import com.ricchieri.common.BusinessSettings;
import com.ricchieri.common.CustomScheduleEvent;
import com.ricchieri.filter.ScheduleCharterFilter;
import com.ricchieri.filter.TripFilter;
import com.ricchieri.filter.UserFilter;
import com.ricchieri.lazymodel.UserLazyDataModel;
import com.ricchieri.model.Reservation;
import com.ricchieri.model.ScheduleCharter;
import com.ricchieri.model.Trip;
import com.ricchieri.model.User;
import com.ricchieri.service.interf.IDocumentTypeService;
import com.ricchieri.service.interf.IUserService;
import com.ricchieri.util.FacesUtil;
import com.ricchieri.util.StringUtils;

@ManagedBean(name = "addReservationMB")
@ViewScoped
public class AddReservationManageBean extends CommonReservationManageBean {
	private static final long serialVersionUID = -7001021047911879866L;
	
	@ManagedProperty(value = "#{DocumentTypeService}")
	IDocumentTypeService documentTypeService;
	
	@ManagedProperty(value = "#{UserService}")
	IUserService userService;
	
	@ManagedProperty(value = "#{addPassengerReservationMB}")
	AddPassengerReservationManageBean addPassengerReservationManageBean;		

	@ManagedProperty(value = "#{editPassengerReservationMB}")
	EditPassengerReservationManageBean editPassengerReservationManageBean;

	private UserFilter userFilter = new UserFilter();
	private User selectedUser;
	
	private UserLazyDataModel userLazyDataModel;
	private Reservation reservation = new Reservation();
	private CustomScheduleEvent event = new CustomScheduleEvent();	
	
	private final String TAB_CALENDAR = "calendar";
	private final String TAB_USER = "user";
	private final String TAB_TRAVEL_DATA = "travelData";
	private final String TAB_CONFIRMATION = "confirmation";
	private String actualTab = TAB_CALENDAR;
	
	private Map<String,String> documents = null;
	private Boolean skipUser = Boolean.FALSE;
	private Boolean skipSchedule = Boolean.FALSE;
	
	@PostConstruct
	public void init() {
		String newReservationOption = (String) FacesUtil.getParametersFlash(BusinessSettings.KEY_ADD_RESERVATION);
		Reservation newReservation = (Reservation) FacesUtil.getParametersFlash(BusinessSettings.KEY_RESERVATION);
		
		if(StringUtils.isNotEmpty(newReservationOption) && newReservationOption.equals(BusinessSettings.KEY_ADD_RESERVATION_USER)) {
			selectedUser = newReservation.getUser();
			skipUser = Boolean.TRUE;
		}
		
		if(StringUtils.isNotEmpty(newReservationOption) && newReservationOption.equals(BusinessSettings.KEY_ADD_RESERVATION_SCHEDULE)) {
			setScheduleCharter(newReservation.getScheduleCharter());
			reservation.setCost(newReservation.getCost());
			reservation.setDownOn(newReservation.getDownOn());
			reservation.setReservationType(newReservation.getReservationType());
			reservation.setUpOn(newReservation.getUpOn());
			reservation.setObservation(newReservation.getObservation());
			reservation.setMeanPayment(newReservation.getMeanPayment());
			reservation.setPassengerType(newReservation.getPassengerType());
			
			getScheduleCharterFilter().setTrip(String.valueOf(getScheduleCharter().getTrip().getId()));
			skipSchedule = Boolean.TRUE;
		}
	}

	public CustomScheduleEvent getEvent() {
		return event;
	}

	public void setEvent(CustomScheduleEvent event) {
		this.event = event;
	}

	public void onEventSelect(SelectEvent selectEvent) {
		event = (CustomScheduleEvent) selectEvent.getObject();
		
		TripFilter tripFilter = new TripFilter();
		tripFilter.setId(getScheduleCharterFilter().getTripId());
		Trip trip = getTripService().getTripById(tripFilter);
		
		//TODO HARDCODE
		if(tripFilter.getId() == 1) {
			reservation.setDownOn("Obelisco/Diagonal");
			reservation.setUpOn("Alvear 534 (Oficina)");			
		} else {
			reservation.setUpOn("Obelisco/Diagonal");
			reservation.setDownOn("Alvear 534 (Oficina)");
		}
		//TODO HARDCODE
		
		reservation.setCost(trip.obtainPriceInPeriod(event.getStartDate()).getCost());
	}

	public void onDateSelect(SelectEvent selectEvent) {
		event = new CustomScheduleEvent("", (Date) selectEvent.getObject(),
				null, null, null, null);
		event.setEndDate(event.getStartDate());
	}

	public String onFlowProcess(FlowEvent event) {  
		
		if(event.getOldStep().equals(this.TAB_CALENDAR)) {
			actualTab = this.TAB_USER;
			if(skipUser) {
				actualTab = this.TAB_TRAVEL_DATA;
				return this.TAB_TRAVEL_DATA;
			}
		} else if(event.getOldStep().equals(this.TAB_USER)) {
			if(event.getNewStep().equals(this.TAB_TRAVEL_DATA)) {
				actualTab = this.TAB_TRAVEL_DATA;
				if(skipSchedule) {
					actualTab = this.TAB_CONFIRMATION;
					return this.TAB_CONFIRMATION;
				}
				
			} else {
				actualTab = this.TAB_CALENDAR;
			}
		} 
		
		return event.getNewStep();
    }
	
	public String skipStep() {
		if(actualTab.equals(this.TAB_CALENDAR) && skipSchedule) {
			return this.TAB_USER;
		}
		
		return this.TAB_CALENDAR;
	}
	
	public Boolean showBackButton() {
		if(this.actualTab.endsWith(this.TAB_CALENDAR)) {
			return Boolean.FALSE;
		} else if(this.actualTab.endsWith(this.TAB_USER)) {
			return Boolean.TRUE;
		} else {
			return Boolean.TRUE;
		}
	}
	
	public Boolean selectEvent() {
		this.actualTab = this.TAB_USER;
		setScheduleCharter(event.getScheduleCharter());
		
		RequestContext context = RequestContext.getCurrentInstance();
		context.addCallbackParam("isValid", true);
		return true;
	}
	
	public void validateTravelData() {
		Boolean isValid = Boolean.TRUE;

		if(StringUtils.isEmpty(reservation.getUpOn())) {
			isValid = Boolean.FALSE;
			FacesUtil.addErrorMsg(getFormName().concat(":upOn"), "requiredUpOn");
		}
		
		if(StringUtils.isEmpty(reservation.getDownOn())) {
			isValid = Boolean.FALSE;
			FacesUtil.addErrorMsg(getFormName().concat(":downOn"), "requiredDownOn");
		}
		
		if(isValid) {
			completeReservationTypes();
		}
		
		RequestContext context = RequestContext.getCurrentInstance();
		context.addCallbackParam("isValid", isValid);
	}

	protected String getFormName() {
		return "addReservation";
	}

	public void setDocuments(Map<String, String> documents) {
		this.documents = documents;
	}

	public UserFilter getUserFilter() {
		userFilter.setRole(BusinessSettings.ROLE_PASSANGER);
		return userFilter;
	}

	public void setUserFilter(UserFilter userFilter) {
		this.userFilter = userFilter;
	}
	
	public Map<String, String> getDocuments() {
		if(documents == null) {
			documents = this.getDocumentTypeService().getComboDocuments();
		}
		return documents;
	}

	public IDocumentTypeService getDocumentTypeService() {
		return documentTypeService;
	}

	public void setDocumentTypeService(IDocumentTypeService documentTypeService) {
		this.documentTypeService = documentTypeService;
	}
	
	public IUserService getUserService() {
		return userService;
	}

	public void setUserService(IUserService userService) {
		this.userService = userService;
	}

	public void search() {
		userLazyDataModel = null;
	}
	
	public void reset() {
		userFilter = new UserFilter();
		userLazyDataModel = null;
	}
	
	public UserLazyDataModel getUserLazyDataModel() {
		if(userLazyDataModel == null) {
			userLazyDataModel = new UserLazyDataModel(userService, userFilter);
		}
		return userLazyDataModel;
	}

	public void setUserLazyDataModel(UserLazyDataModel userLazyDataModel) {
		this.userLazyDataModel = userLazyDataModel;
	}
	
	public User getSelectedUser() {
		return selectedUser;
	}

	public void setSelectedUser(User selectedUser) {
		this.selectedUser = selectedUser;
	}
	
	public String saveReservation() {
		reservation.setScheduleCharter(getScheduleCharter());
		reservation.setReservationDate(new Date());
		reservation.setUser(selectedUser);
		
		ScheduleCharterFilter filter = new ScheduleCharterFilter();
		filter.setId(getScheduleCharter().getId());
		filter.setTrip(getScheduleCharterFilter().getTrip());
		ScheduleCharter newScheduleCharter = getScheduleCharterService().getScheduleCharterByFilter(filter);
			
		if(newScheduleCharter.getCharter() != null && newScheduleCharter.getQuantityReserved() >= newScheduleCharter.getCharter().getPlaces()) {
			FacesUtil.showFatalMessage("addReservation","noCapacity" );
			return BusinessSettings.UNSUCCESS;
		} else if (this.haveReservation(selectedUser)) {
			FacesUtil.showFatalMessage("addReservation","reservationExist" );
			return BusinessSettings.UNSUCCESS;
		} else {
			getReservationService().addReservation(reservation);
			FacesUtil.addParametersFlash(BusinessSettings.KEY_RESERVATION, reservation);
			
			return BusinessSettings.SUCCESS;
		}
	}

	public Reservation getReservation() {
		return reservation;
	}

	public void setReservation(Reservation reservation) {
		this.reservation = reservation;
	}

	public AddPassengerReservationManageBean getAddPassengerReservationManageBean() {
		return addPassengerReservationManageBean;
	}

	public void setAddPassengerReservationManageBean(
			AddPassengerReservationManageBean addPassengerReservationManageBean) {
		this.addPassengerReservationManageBean = addPassengerReservationManageBean;
	}
	
	public void resetUser() {
		getAddPassengerReservationManageBean().reset();
	}
	
	public void saveUser() {
		RequestContext context = RequestContext.getCurrentInstance();
		String result = getAddPassengerReservationManageBean().save();
		
		if(BusinessSettings.UNSUCCESS == result) {			
			context.addCallbackParam("isValid", false); 
		} else {
			context.addCallbackParam("isValid", true); 
			selectedUser =  getAddPassengerReservationManageBean().getUser();
			actualTab = this.TAB_CONFIRMATION;
		}	
	}
	
	public Boolean showUserSelection(User user) {
		return !user.getBlock() && !haveReservation(user);
	}
	
	public void editUser() {
		this.getEditPassengerReservationManageBean().setPassanger(getUserLazyDataModel().getRowData());
	}

	public EditPassengerReservationManageBean getEditPassengerReservationManageBean() {
		return editPassengerReservationManageBean;
	}

	public void setEditPassengerReservationManageBean(
			EditPassengerReservationManageBean editPassengerManageBean) {
		this.editPassengerReservationManageBean = editPassengerManageBean;
	}
	
	
	public void saveChangesUser() {
		RequestContext context = RequestContext.getCurrentInstance();
		String result = getEditPassengerReservationManageBean().save();
		
		if(BusinessSettings.UNSUCCESS == result) {			
			context.addCallbackParam("isValid", false); 
		} else {
			context.addCallbackParam("isValid", true); 
			selectedUser =  getEditPassengerReservationManageBean().getUser();
			actualTab = this.TAB_CONFIRMATION;
		}	
	}
	
	
}
